// s3efpga.v - Top level module for digilent spartan 6 FPGA board as used in project 3
//
// Created By:	Jesse Inkpen
// Date:	30-October-2012
//
// Description:
// ------------
// Top level module for project 3 on the Digilent Nexys3 Spartan-6 
//
// Use the pushbuttons to control the encription logic:
//	btns		btn_center	reset
//	btnd		btn_down	load encription engine	
//	btnr 		btn_right	go, start the encription engine
//	btnu 		btn_up		stop the encription engine	
//	btnl 		btn_left        not used
//
// Use the switches to control the data that is loaded into the encription engine
//	SW 0 		_public key_ / private key
//	SW 1 - 7 	_plain text_ / encripted word pairs
//
//	LED light up for legitimate switch configurations.
//	
//	The Display shows the loaded message, and post processing message
///////////////////////////////////////////////////////////////////////////

`define BITS 16

module s6efpga (
	input 			clk100,          	// 100MHz clock from on-board oscillator
	input			btnl, btnr,		// pushbutton inputs - left and right
	input			btnu, btnd,		// pushbutton inputs - top and bottom
	input			btns,			// pushbutton inputs - center button
	input	[7:0]		sw,			// switch inputs
	
	output	[7:0]		led,  			// LED outputs	
	
	output 	[7:0]		seg,			// Seven segment display cathode pins
	output	[3:0]		an,			// Seven segment display anode pins	
	
	output	[3:0]		JA			// JA Header
); 

	// internal variables
	wire [7:0]		db_sw;			// debounced switches
	wire [4:0]		db_btns;		// debounced buttons
								
	wire			sysclk;			// 100MHz clock from on-board oscillator	
	wire			sysreset;		// system reset signal - asserted high to force reset
	
	wire [4:0]		dig3, dig2, dig1, dig0;	// display digits
	wire [3:0]		decpts;			// decimal points
	wire [7:0]		chase_segs;		// chase segments from Rojobot (debug)

	
	// RSA Hacks	
	wire			d;			// result done signal
	wire [`BITS-1:0] 	r;			// output result
	wire [`BITS-1:0]	m;			// input message
	wire [`BITS-1:0]	e;			// exponent
	wire [`BITS-1:0]	n;			// modulous
	
	wire [`BITS-1:0]	M;			// input message
	wire [`BITS-1:0]	E;			// exponent
	wire [`BITS-1:0]	N;			// modulous
	wire 			GO;				// encription control signal
	wire 			RESET;			// RESET signal
	wire			LOAD;				// memory control signal
	wire			DONE;				// RESULT latched in memory signal
	wire [`BITS-1:0] 	RESULT;	// result in lelory for display
	wire 			ready_conn;			//Used for checking whether MontProd is ready or not
	wire [`BITS-1:0] result_conn;	//MontProd result	
	wire start_conn;
	wire [`BITS-1:0] A_conn;
	wire [`BITS-1:0] B_conn;
	wire [`BITS-1:0] MOD_conn;
	
	wire [15:0]		display;		// lower 16 bits of result displayed  
	assign	dig3 = {1'b0,display[15:12]};
	assign	dig2 = {1'b0,display[11:8]};
	assign 	dig1 = {1'b0,display[7:4]};
	assign	dig0 = {1'b0,display[3:0]};
	assign	decpts = {4'b00,GO,DONE};		// display state as decimal points
	
/******************************************************************/
/* CHANGE THIS SECTION FOR YOUR PROJECT 3                            */
/******************************************************************/		

	wire [31:0] digits_out;		// ASCII digits (Only for Simulation)
	wire div_clock;
	
	// global assigns
	assign	sysclk = div_clock;
	assign 	sysreset = db_btns[0];
	assign	JA = {0, sysreset, 2'b0};

	DCM_divide clock_divider
   (// Clock in ports
    .CLK_IN1(clk100),      // IN
    // Clock out ports
    .CLK_OUT1(div_clock));    // OUT

	STIMULOUS stim(
		.CLK(sysclk),
		.PB(db_btns),
		.SW(db_sw),
		.GO(GO),
		.RESET(RESET),
		.LOAD(LOAD),
		.M(M),
		.E(E),
		.N(N),
		.RESULT(RESULT),
		.DONE(DONE),
		.display(display),
		.led(led)
	);
	  
	MEMORY mem(
		.CLK(sysclk),
		.RESET(RESET),
		.LOAD(LOAD),
		.M(M),
		.E(E),
		.N(N),		
		.m(m),
		.e(e),
		.n(n),
		.r(r),
		.done(d),
		.RESULT(RESULT),
		.DONE(DONE)
	); 
	  
	 RSA encr(
		.clk(sysclk),
		.go(GO),
		.m(m),	
		.e(e),	
		.n(n),	
		.ready(ready_conn),
		.result(result_conn),
		.r(r),	
		.d(d),	
		.start(start_conn),
		.A(A_conn),
		.B(B_conn),
		.M(MOD_conn)
	 );

	 MontProd 	MONTPROD(
		.clk(sysclk),
		.start(start_conn),
		.A(A_conn),
		.B(B_conn),
		.M(MOD_conn),
		.done(ready_conn),
		.result(result_conn)
	);

/******************************************************************/
/* THIS SECTION SHOULDN'T HAVE TO CHANGE FOR PROJECT 3               */
/******************************************************************/			
	
	// instantiate the debounce module
	
	debounce 	DB (
		.clk(sysclk),	
		.pbtn_in({btnl,btnu,btnr,btnd,btns}),
		.switch_in(sw),
		.pbtn_db(db_btns),
		.swtch_db(db_sw)
	);	
		
// instantiate the 7-segment, 4-digit display
	SevenSegment SSB (
		// inputs for control signals
		.d0(dig0),
		.d1(dig1),
 		.d2(dig2),
		.d3(dig3),
		.dp(decpts),
		// outputs to seven segment display
		.seg(seg),			
		.an(an),				
		// clock and reset signals (100 MHz clock, active high reset)
		.clk(sysclk),
		.reset(sysreset),
		// ouput for simulation only
		.digits_out(digits_out)
	);
	
endmodule
	